package com.qq.多线程.线程池;


import java.util.concurrent.*;

/*
 * 
  	ExecutorService的常用方法
	void execute(Runnable command) 		执行任务/命令，没有返回值，一般用来执行 Runnable 任务
	Future<T> submit(Callable<T> task)	执行任务，返回未来任务对象，通过get获取线程结果，一般拿来执行 Callable 任务
	void shutdown() 					等任务执行完毕后关闭线程池
	List<Runnable> shutdownNow()		立刻关闭，停止正在执行的任务，并返回队列中未执行的任务
	
	FutureTask方法：
	public V get() throws Exception		获取线程执行call方法返回的结果。
	
	注，线程池Callable 和自己创建线程对象
	1.自己创建Thread线程对象，需要把Callable可返回 任务对象封装成FutureTask任务对象
	     再把FutureTask（Runnable接口和future接口的实现类）交给Thread对象，调用get方法得到任务返回值
	       
	2.使用线程池的submit方法，我们只需要把Callable可返回 任务对象交给线程池执行，
	     它会返回一个Future类型对象（真实类型为FutureTask），调用Future的get方法得到任务返回值
	    
	
    目标：自定义一个线程池对象，并测试其特性。
 */
public class ThreadPool_Test2 {
    public static void main(String[] args) throws Exception {
        // 1、创建线程池对象
        /*
         public ThreadPoolExecutor(int corePoolSize,
                                 int maximumPoolSize,
                                 long keepAliveTime,
                                 TimeUnit unit,
                                 BlockingQueue<Runnable> workQueue,
                                 ThreadFactory threadFactory,
                                 RejectedExecutionHandler handler)
         */
        ExecutorService pool = new ThreadPoolExecutor(3, 5 ,
                6, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), 
                 Executors.defaultThreadFactory(),//可以不写，自动使用默认线程工厂
               new ThreadPoolExecutor.AbortPolicy() );//可以不写，自动使用默认拒绝策略

        // 2、给任务线程池处理。
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));//三个任务给核心线程
        
        Future<String> f4 = pool.submit(new MyCallable(400));//在队列
        Future<String> f5 = pool.submit(new MyCallable(500));//给临时线程

//        String rs = f1.get();
//        System.out.println(rs);
        System.out.println(f1.get());//get方法会等线程执行完再返回结果
        System.out.println(f2.get());
        System.out.println(f3.get());//出现异常下面的执行不了
        System.out.println(f4.get());
        System.out.println(f5.get());
       
//      注：使用submit提交Callable任务时如果有一个任务出现了异常，还是会创建新的线程执行任务      
//      但是 ，此时get方法处会获取不到返回值出现异常，下面的get方法就都执行不了了
        
        
        
        
        
        
        
        

    }
}
